package demo.controller;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import demo.bean.LazyInitBean;
import io.micrometer.core.instrument.Metrics;
import util.AppUtil;
import util.CommUtil;
import util.JmxUtil;
import util.MetricsUtil;
import util.MsgUtil;
import util.StatusUtil;

@RestController
@Lazy
public class StatusController {
	
	
	private static final Logger log = LoggerFactory.getLogger(StatusController.class);
	
	
	// 注意 StatusController 使用 @Lazy ， 否则 LazyInitBean 无法 延迟加载
	@Autowired
	private LazyInitBean lazyInitBean;
	
	private final String createTime = LocalDateTime.now().toString();

	
	public StatusController(){
		System.out.println(this.getClass().getSimpleName()+" run "+LocalDateTime.now());
	}
	
	@RequestMapping("/status")
	public Object status(HttpServletRequest request)throws Exception{
		Map map = new HashMap();
		
		try{
			Metrics.counter("statusInvokeCount7").increment();
			MetricsUtil.statusInvokeCount.getAndIncrement();
			long start = System.currentTimeMillis();
			status_(request,map);
			long end = System.currentTimeMillis();
			long time = end - start;

			Metrics.timer("statusInvokeTime").record(time, TimeUnit.MILLISECONDS);
			
		}catch(Throwable e){
			map.put("error", e+"");
			map.put("errorStack", CommUtil.getErrorInfo(e));
			log.error("status run error", e);

		}
		String safe = request.getParameter("safe");
		if(safe!=null){
			return map.get("data").toString();
		}

		return map;
	}
	
	private void status_(HttpServletRequest request,Map map)throws Exception{
		String type = request.getParameter("type");
		
		if("listAllMsg".equals(type)){
			
			map.put("data", MsgUtil.listAll());		
			return;
		}
		
		
		
		if("clearcount".equals(type)){
			MetricsUtil.increment(type);
			MetricsUtil.clear();
			map.put("data", "clearcount done "+LocalDateTime.now());
			
			return;
		}
		
		if("countmap".equals(type)){
			MetricsUtil.increment(type);

			map.put("data", MetricsUtil.getCountMap());		
			return;
		}
		
		if("jmxbeans".equals(type)){
			MetricsUtil.increment(type);

			map.put("data", JmxUtil.queryAsString(null));
			return;
		}
		
		if("args".equals(type)){
			MetricsUtil.increment(type);

			map.put("data", StatusUtil.get("args"));
			return;
		}
		
		if("jmx".equals(type)){
			MetricsUtil.increment(type);

			map.put("data", JmxUtil.getMBeanAttributeValuesAll());
			return;
		}
		
		if("jmxbean".equals(type)){
			MetricsUtil.increment(type);

			String name = request.getParameter("name");
			if(CommUtil.isBlank(name)){
				map.put("error", "bean name blank");
				return;
			}
			map.put("data", JmxUtil.getMBeanAttributeValues(name));
			return;
		}
		
		if("lazyBean".equals(type)){
			MetricsUtil.increment(type);

			 
			
			// LazyInitBean lazyInitBean = (LazyInitBean)AppUtil.getBean("lazyInitBean");
			
			map.put("data", lazyInitBean.toString());	
			map.put("status.createTime", createTime);	
			map.put("AppUtil.createTime", AppUtil.getCreateTime());	

			
			return;
		}
		
		map.put("error", "type error");
	}

	
	
		
}